#!/usr/bin/env python3
# -*- coding=utf-8 -*-
# 本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
# 教主QQ:605658506
# 亁颐堂官网www.qytang.com
# 教主技术进化论拓展你的技术新边疆
# https://ke.qq.com/course/271956?tuin=24199d8a

from django.shortcuts import render
from devnet.models import Department, Navbar
from devnet.models import Devicedb, MonitorInterval, DeviceInterface
from datetime import datetime, timedelta
from django.db.models import Max
import numpy as np
from django.contrib.auth.decorators import login_required

try:
    cpu_max_interval = MonitorInterval.objects.get(name='cpu_max_interval').interval
except MonitorInterval.DoesNotExist:
    c = MonitorInterval(name='cpu_max_interval',
                        interval=1)
    c.save()
    cpu_max_interval = MonitorInterval.objects.get(name='cpu_max_interval').interval


try:
    mem_max_interval = MonitorInterval.objects.get(name='mem_max_interval').interval
except MonitorInterval.DoesNotExist:
    m = MonitorInterval(name='mem_max_interval',
                        interval=1)
    m.save()
    mem_max_interval = MonitorInterval.objects.get(name='mem_max_interval').interval


@login_required()
def home(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '首页'
    devices_cpu_list = []
    devices_mem_list = []
    top_3_if_utilization_rx_dict = []
    top_3_if_utilization_tx_dict = []
    for device in Devicedb.objects.all():
        cpu_max = device.cpu_usage.filter(record_datetime__gt=datetime.now() - timedelta(hours=cpu_max_interval)).aggregate(Max('cpu_usage')).get('cpu_usage__max')
        try:
            cpu_current = device.cpu_usage.all().order_by('-id')[0].cpu_usage
            devices_cpu_list.append({'name': device.name, 'cpu_max': cpu_max, 'cpu_current': cpu_current})
            devices_cpu_list = sorted(devices_cpu_list, key=lambda y: y['cpu_max'], reverse=True)
            devices_cpu_list = devices_cpu_list[:3]
        except IndexError:
            continue
        except TypeError:
            continue

        try:
            mem_max = device.mem_usage.filter(record_datetime__gt=datetime.now() - timedelta(hours=mem_max_interval)).aggregate(Max('mem_usage')).get('mem_usage__max')
            mem_current = device.mem_usage.all().order_by('-id')[0].mem_usage
            devices_mem_list.append({'name': device.name, 'mem_max': mem_max, 'mem_current': mem_current})
            devices_mem_list = sorted(devices_mem_list, key=lambda y: y['mem_max'], reverse=True)
            devices_mem_list = devices_mem_list[:3]
        except IndexError:
            continue
        except TypeError:
            continue

    active_inteface = []
    for interface in DeviceInterface.objects.all():
        try:
            if interface.interface_out_bytes.order_by('-id')[0].out_bytes > 0 and interface.interface_in_bytes.order_by('-id')[0].in_bytes > 0:
                active_inteface.append(interface)
            else:
                continue
        except Exception:
            continue
    for interface in active_inteface:
        # 入方向利用率
        interface_in_data = interface.interface_in_bytes.filter(record_datetime__gt=datetime.now() - timedelta(hours=1))
        in_bytes_list = []
        in_bytes_time = []
        for x in sorted(interface_in_data, key=lambda k: k.record_datetime):
            in_bytes_list.append(x.in_bytes)
            in_bytes_time.append(x.record_datetime)

        diff_if_in_bytes_list = list(np.diff(in_bytes_list))

        diff_if_in_record_time_list = [x.seconds for x in np.diff(in_bytes_time)]

        zip_in_list = zip(diff_if_in_bytes_list, diff_if_in_record_time_list)

        interface_speed = interface.interface_speed.speed

        utilization_in_data = list(map(lambda x: round(((x[0] * 8) / x[1] / interface_speed) * 100, 2), zip_in_list))
        try:
            top_3_if_utilization_rx_dict.append({'name': interface.device.name, 'ifname': interface.interface_name, 'rx_max': max(utilization_in_data), 'rx_current': utilization_in_data[-1]})
        except ValueError:
            top_3_if_utilization_rx_dict.append({'name': interface.device.name, 'ifname': interface.interface_name, 'rx_max': 0, 'rx_current': 0})
        # 出方向利用率
        interface_out_data = interface.interface_out_bytes.filter(record_datetime__gt=datetime.now() - timedelta(hours=1))
        out_bytes_list = []
        out_bytes_time = []
        for x in sorted(interface_out_data, key=lambda k: k.record_datetime):
            out_bytes_list.append(x.out_bytes)
            out_bytes_time.append(x.record_datetime)

        diff_if_out_bytes_list = list(np.diff(out_bytes_list))

        diff_if_out_record_time_list = [x.seconds for x in np.diff(out_bytes_time)]

        zip_out_list = zip(diff_if_out_bytes_list, diff_if_out_record_time_list)

        utilization_out_data = list(map(lambda x: round(((x[0] * 8) / x[1] / interface_speed) * 100, 2), zip_out_list))
        try:
            top_3_if_utilization_tx_dict.append({'name': interface.device.name, 'ifname': interface.interface_name, 'tx_max': max(utilization_out_data), 'tx_current': utilization_out_data[-1]})
        except ValueError:
            top_3_if_utilization_tx_dict.append({'name': interface.device.name, 'ifname': interface.interface_name, 'tx_max': 0, 'tx_current': 0})
    top_3_if_utilization_rx_dict = sorted(top_3_if_utilization_rx_dict, key=lambda y: y['rx_max'], reverse=True)
    top_3_if_utilization_rx_dict = top_3_if_utilization_rx_dict[:3]

    top_3_if_utilization_tx_dict = sorted(top_3_if_utilization_tx_dict, key=lambda y: y['tx_max'], reverse=True)
    top_3_if_utilization_tx_dict = top_3_if_utilization_tx_dict[:3]
    return render(request, 'devnet_home.html', locals())
